package org.jaaksi.demo.ptr.ui.recycler;

import android.app.Activity;
import android.graphics.Color;
import android.os.Bundle;
import android.os.Handler;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import com.chad.library.adapter.base.BaseQuickAdapter;
import com.chad.library.adapter.base.BaseViewHolder;
import com.chad.library.adapter.base.loadmore.LoadMoreView;
import in.srain.cube.views.ptr.PtrClassicFrameLayout;
import in.srain.cube.views.ptr.PtrDefaultHandler;
import in.srain.cube.views.ptr.PtrFrameLayout;
import in.srain.cube.views.ptr.PtrHandler;
import in.srain.cube.views.ptr.PtrUIHandler;
import in.srain.cube.views.ptr.header.StoreHouseHeader;
import java.util.List;
import org.jaaksi.demo.ptr.R;
import org.jaaksi.demo.ptr.ui.base.StateLayout;
import org.jaaksi.demo.ptr.util.DensityUtil;
import org.jaaksi.demo.ptr.util.SysUtil;

/**
 * Created by an on 2017/5/10.<br/>
 * 下拉和加载更多是互斥的
 */

public class BaseRecyclerViewFragment<T> extends Fragment
    implements BaseQuickAdapter.RequestLoadMoreListener {

  private Activity mContext;
  private Handler mHandler = new Handler();
  private RecyclerView mRecyclerView;
  private LinearLayoutManager mLayoutManager;
  private PtrClassicFrameLayout mRefreshView;
  private RequestCallback mRequestCallback;
  private View mPtrHeader;

  private StateLayout mStateLayout;
  private BaseQuickAdapter<T, ? extends BaseViewHolder> mAdapter;
  private LoadMoreView mLoadMoreView;

  /**
   * 刷新还是加载更多
   */
  private boolean mIsRefresh = true;
  private boolean mAutoLoading = true;
  private boolean mAutoLoadByPtr = false;
  private boolean mIsPinContent = false;
  // 没有更多了是否显示LoadMoreView
  private boolean mShowNoMore = true;
  private boolean mEnablePtr = true;

  private int mCurrPage;
  private int mPageSize = 10;

  @Nullable @Override
  public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container,
      @Nullable Bundle savedInstanceState) {
    mContext = getActivity();
    View view = inflater.inflate(getLayoutId(), container, false);
    mRefreshView = initRefreshView(view);
    if (!mEnablePtr) {
      setPtrEnable(false);
    }
    mRecyclerView = (RecyclerView) view.findViewById(R.id.list);
    mStateLayout = (StateLayout) view.findViewById(R.id.state_layout);
    // 这个建议全局一致，直接在基类设置即可，不提供动态设置
    //mStateLayout.setLoadingView();
    mStateLayout.setOnRetryListener(new View.OnClickListener() {
      @Override public void onClick(View v) {
        refresh(false);
      }
    });

    mLayoutManager = new LinearLayoutManager(mContext);
    mLayoutManager.setOrientation(LinearLayoutManager.VERTICAL);
    mRecyclerView.setLayoutManager(mLayoutManager);
    init(view);

    // 这里参数是个抽象类就不好了，应该搞成接口
    if (mLoadMoreView != null) {
      mAdapter.setLoadMoreView(mLoadMoreView);
    }
    mAdapter.setOnLoadMoreListener(this, mRecyclerView);
    // 动画可以在子类设置
    //mAdapter.openLoadAnimation(BaseQuickAdapter.SLIDEIN_LEFT);
    mRecyclerView.setAdapter(mAdapter);

    if (mAutoLoading) {
      if (!mAutoLoadByPtr) {
        refresh(false);
      } else {
        // 如果使用ptr需要延迟
        mHandler.postDelayed(new Runnable() {
          @Override public void run() {
            mRefreshView.autoRefresh(true);
          }
        }, 100);
      }
    }

    return view;
  }

  protected int getLayoutId() {
    return R.layout.lib_ptr_recyclerview;
  }

  public BaseRecyclerViewFragment<T> setPtrHeader(View header) {
    if (!(header instanceof PtrUIHandler)) {
      throw new IllegalArgumentException("header view must implements PtrUIHandler interface");
    }
    this.mPtrHeader = header;
    return this;
  }

  /**
   * 设置loadmoreview
   *
   * @param loadMoreView loadMoreView
   */
  public BaseRecyclerViewFragment<T> setLoadMoreView(LoadMoreView loadMoreView) {
    this.mLoadMoreView = loadMoreView;
    return this;
  }

  protected View userDefaultPtrHeader() {
    // header
    final StoreHouseHeader header = new StoreHouseHeader(mContext);
    header.setPadding(0, DensityUtil.dip2px(mContext, 15), 0, 0);
    header.setTextColor(Color.parseColor("#FF4081"));
    header.initWithString("freshhub");
    return header;

    //final MaterialHeader header = new MaterialHeader(mContext);
    //int[] colors = getResources().getIntArray(R.array.google_colors);
    //header.setColorSchemeColors(colors);
    //header.setLayoutParams(new PtrFrameLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
    //    ViewGroup.LayoutParams.WRAP_CONTENT));
    //header.setPadding(0, DensityUtil.dip2px(mContext, 15), 0, DensityUtil.dip2px(mContext, 10));
    //return header;
  }

  private PtrClassicFrameLayout initRefreshView(View view) {
    PtrClassicFrameLayout ptr = (PtrClassicFrameLayout) view.findViewById(R.id.ptr_view);
    // 设置下拉时内容是否随着header下拉
    ptr.setPinContent(mIsPinContent);
    // 自定义headerview
    if (mPtrHeader == null) {
      mPtrHeader = userDefaultPtrHeader();
    }
    ptr.setHeaderView(mPtrHeader);
    ptr.addPtrUIHandler((PtrUIHandler) mPtrHeader);
    ptr.setPtrHandler(new PtrHandler() {
      @Override
      public boolean checkCanDoRefresh(PtrFrameLayout ptrFrameLayout, View view, View header) {
        return PtrDefaultHandler.checkContentCanBePulledDown(ptrFrameLayout, mRecyclerView, header);
      }

      @Override public void onRefreshBegin(PtrFrameLayout ptrFrameLayout) {
        refresh();
      }
    });
    return ptr;
  }

  protected void init(View view) {
  }

  // fixme 所有的方法都应该通过设置的方式，这样Activity中才能使用
 /* protected View initChildHeadView() {
    return null;
  }*/

  public BaseRecyclerViewFragment<T> setRequestCallback(RequestCallback callback) {
    this.mRequestCallback = callback;
    return this;
  }

  public BaseRecyclerViewFragment<T> adapter(
      BaseQuickAdapter<T, ? extends BaseViewHolder> adapter) {
    this.mAdapter = adapter;
    return this;
  }

  public BaseRecyclerViewFragment<T> enablePtr(boolean enable) {
    this.mEnablePtr = enable;
    return this;
  }

  /**
   * 下拉时内容是否跟随,如果使用
   */
  public BaseRecyclerViewFragment<T> pinContent(boolean isPinContent) {
    this.mIsPinContent = isPinContent;
    return this;
  }

  /**
   * 是否允许第一次自动加载
   */
  public BaseRecyclerViewFragment<T> autoLoading(boolean autoLoading) {
    this.mAutoLoading = autoLoading;
    return this;
  }

  /**
   * 没有更多时是否显示
   */
  public BaseRecyclerViewFragment<T> showNoMore(boolean showNoMore) {
    this.mShowNoMore = showNoMore;
    return this;
  }

  /**
   * 设置第一次自动加载的方式，ptr还是loading
   */
  public BaseRecyclerViewFragment<T> autoLoadingStyle(boolean isPtr) {
    this.mAutoLoadByPtr = isPtr;
    return this;
  }

  public BaseRecyclerViewFragment<T> pageSize(int pageSize) {
    this.mPageSize = pageSize;
    return this;
  }

  /**
   * 设置ptr是否可用，如果是初始化请使用{@link #enablePtr(boolean)}
   */
  public void setPtrEnable(boolean enable) {
    mRefreshView.setEnabled(enable);
  }

  /**
   * 使用loading 进行刷新，需要在结束后手动关闭
   */
  public void loadingClose() {
    mStateLayout.setState(StateLayout.NORMAL);
  }

  public RecyclerView getRecyclerView() {
    return mRecyclerView;
  }

  protected List<T> getItems() {
    return mAdapter.getData();
  }

  public int getPageSize() {
    return mPageSize;
  }

  public int getOffset() {
    return mCurrPage * mPageSize;
  }

  private boolean isAdapterEmpty() {
    return mAdapter.getData().size() == 0;
  }

  public void refresh() {
    refresh(true);
  }

  /**
   * 刷新方法
   *
   * @param isPullRefresh 是否是下拉刷新
   */
  public void refresh(boolean isPullRefresh) {
    // 刷新的时候禁止加载更多，请求执行完成后才开启
    mAdapter.setEnableLoadMore(false);
    mIsRefresh = true;
    mCurrPage = 0;
    mRecyclerView.scrollToPosition(0);
    if (isPullRefresh) {
      mStateLayout.setState(StateLayout.NORMAL);
    } else {
      mStateLayout.setState(StateLayout.LOADING);
    }
    buildRequest();
  }

  /**
   * 发送请求，如果是Fragment直接重写改方法即可，如果是Activity需要{@link #setRequestCallback(RequestCallback)}
   */
  protected void buildRequest() {
    if (mRequestCallback != null) {
      mRequestCallback.doRequest();
    }
  }

  /**
   * 如果使用服务器hasmore字段，就必须调用这个方法（推荐使用如果可以）
   *
   * @param list 当数据异常得到的list为null时，setDatas(null)即可
   * @param hasMore 是否有更多（来自服务器的字段）
   */
  public void setDatas(List<T> list, boolean hasMore) {
    if (mIsRefresh) {
      if (!isAdapterEmpty()) {
        mAdapter.getData().clear();
      }

      if (mRefreshView.isRefreshing()) { // ptr的刷新
        mRefreshView.refreshComplete();
      } else {
        loadingClose();
      }
      mAdapter.setEnableLoadMore(true);
    } else {
      setPtrEnable(true);
    }

    if (list == null) {
      if (mIsRefresh) {
        if (!SysUtil.isNetworkAvailable(mContext)) {
          mStateLayout.setState(StateLayout.NO_NET);
        } else {
          mStateLayout.setState(StateLayout.SERVER_ERROR);
        }
        // TODO 刷新的时候应该把loadmoreview的状态清除
        // 这个下拉的时候就调用了mAdapter.setEnableLoadMore(false)应该就没了吧
      } else { // 加载更多，证明已经有数据了，并不清空已有数据，不设置error状态
        // TODO 加载更多失败,如果loadmore的时候服务器拿不到数据，就认为hasMore=true，以便可以再次加载
        mAdapter.loadMoreFail();
      }
    } else if (list.isEmpty() && isAdapterEmpty() && mIsRefresh) { // 刷新时，没有数据，即0个非null（server异常）
      mStateLayout.setState(StateLayout.NO_DATA);
    } else {
      mStateLayout.setState(StateLayout.NORMAL);
      mAdapter.addData(list);
      //if (!mIsRefresh) {
      mCurrPage++;
      //}
      if (!hasMore) {
        // 这个参数表示是否隐藏，比如没有更多了可以显示一个提示，但是下次会不会再去加载呢？
        mAdapter.loadMoreEnd(!mShowNoMore);
      } else {
        mAdapter.loadMoreComplete();
      }
    }
    mAdapter.notifyDataSetChanged();
  }

  @Override public void onLoadMoreRequested() {
    // 加载更多
    mIsRefresh = false;
    setPtrEnable(false);
    buildRequest();
  }

  public interface RequestCallback {
    /**
     * 发送请求,避免用buildRequest()方法重名
     */
    void doRequest();
  }
}
